/******************************************************************************
** 
**	File name:		rtos.inc
**	
**	Description:	RTOS internal header. Contains of useful defines and
**					macros that widely used acros RTOS code.
**
**  Notes:			Should not be used by user' code.
**
*******************************************************************************
** History:
**
**	10/01/2010 - AK - Initial version
**	12/18/2011 - AK - Migrating to the new version of the _ENTER_CRITICAL
**					  and _LEAVE_CRITICAL macro
**  07/26/2012 - AK - Removing support for older GCC versions ( 2.xx )
**					  Removing support for ARM MCUs
**
******************************************************************************/
#ifndef __RTOS_INC__
#define __RTOS_INC__

#include "ctoasm.inc"

// Define _IOMACROS_H_ to prevent io.h from including this
// C only file when using io.h for assembly code.  

#define _IOMACROS_H_
#include <avr/io.h>

#define _GLOBAL(Label, Size) .comm Label, Size
#define _STATIC(Label, Size) .lcomm Label, Size
#define _DATASECTION
#define _CODESECTION
#define _FUNCTION(A) \
        .global A $ \
        .func   A
#define _ENDFUNC		.endfunc
#define _PUBLIC(A)		.global A
#define _EXTERN(A)
#define _MODULE(A)		.section .text.rtos.A
#define _ENDMOD
#define _END
#define MACRO			.macro
#define ENDM			.endm

#ifndef BV
#define BV(A) (1<<A)
#endif

/******************************************************************************
** Context Offsets for various registers after the return from
** a call to _EnterISR
**
** Used mainly to restore registers that required internally 
** (rather than push/pop) and to stuff return values across _LeaveISR.
**
******************************************************************************/
#define _RetLo		33      /* Return address on stack is saved as big endian */
#define _R31		33      /* Registers are saved in order (little endian) */
#define _RetHi		32
#define _R30		32
#define _R29		31
#define _R28		30
#define _R27		29
#define _R26		28
#define _R25		27
#define _R24		26
#define _R23		25
#define _R22		24
#define _R0			2
#define _SREG		1       /* SP points below last saved item */

#define _p1l		26
#define _p1h		27
#define _p2l		24
#define _p2h		25
#define _r1l		26
#define _r1h		27

/******************************************************************************
** RTOS kernel data structure offsets
** These are offsets into a global structure called "RtosKernelData"
** defined in rtos_kernel.s
**
** NOTE: CODE depends on RunQueue being the FIRST field in structure!
******************************************************************************/
#define KDATA					RtosKernelData

#define RunQueue 				0	/* Head of the run queue */
#define Running 				2	/* Current running task */
#define RtosStack 				4	/* User defined stack location */
#define SysLevel 				6	/* kernel context level counter */
#define RtosCStack 				7	/* C Parameter stack */

#define RtosKernelDataSz 		7 	

/******************************************************************************
** RTOS TCB (Task Control Block) structure offsets
******************************************************************************/

#define TaskSP          		0   /* Stack pointer */
#define TaskFunc        		2   /* Entry point of process */
#define TaskID          		4   /* Pointer to Process ID */
#define TaskFlags       		6   /* Priority */

#define TaskSz  				7	/* Size of Task Control Block structure */ 

#define OFFSET_TCF_STACK		0
#define OFFSET_TCF_TASK			2
#define OFFSET_TCF_TCB			4
#define OFFSET_TCF_PRIO			6

/******************************************************************************
** All RTOS objects have the same linked list structure
** Change this to convert to big-endian for direct C access
******************************************************************************/

#define RTOS_PID_NEXT			0			/* RTOS_PID.next 	*/
#define RTOS_PID_FLAG			2			/* RTOS_PID.flag 	*/
#define RTOS_PID_PRIO			3			/* RTOS_PID.prio 	*/
#define RTOS_PID_SPTR			4			/* RTOS_PID.sptr 	*/

#define RTOS_PID_SIZE			6			/* sizeof(RTOS_PID) */

#define RTOS_PID_FLAG_IDLE		4			/* (1 << 4) 		*/
#define RTOS_PID_FLAG_SUSPEND	5			/* (1 << 5) 		*/
#define RTOS_PID_FLAG_SUSPENDED	6			/* (1 << 6) 		*/

#define NextL					0	/* Big-endian for C compatibility */
#define NextH					1

/* PID (Pointer to task ID) block offsets */

#define PidNext         		0   /* Next item on list (event, run) */
#define PidState        		2   /* Upper Nibble: Task flags, Lower Nibble :Priority */
#define PidPriority     		3
#define PidSP           		4   /* Context Pointer */
#define PidSz        			6

/* PID.State BLOCK BIT DEFINITIONS */

#define IdleBit         		4   /* Dead Task, don't schedule, resume or step */
#define SuspendBit      		5   /* Mark task for suspension (may be blocked elsewhere) */
#define SuspendedBit    		6   /* Mark task suspended (it was removed from the run queue) */

/******************************************************************************
**
** EVENT BIT DEFINITIONS
** 
** General Event Flags.  When a task is waiting on the event, the event is set 
** to the TASK ID.  Otherwise _PEND means the event is set and _DONE means it 
** has been triggered.  A task will only block if it tries to grab a _PEND 
** event.  Events are initialized in the _PEND state and are left in the _PEND 
** state after each complete operation.  Processes are allowed to queue on
** an event.  This effectively make the event a RtosEvent when it has been 
** "set" prior to the first call.  When a process done with the event, it 
** releases it by "setting" it again.
**
******************************************************************************/
#define _PEND           		0
#define _DONE           		1
#define _WAIT					2

#define EvtSz           		2	/* Size of RTOS_EVT_t */

/******************************************************************************
**
** RTOS Internal Events
**
** Events replace pID's in events.  The kernel recognizes
** event values (contents) < 0x60 as events, indexes into
** a table and calls a routine.  Macros and segments are used
** to build the table.
**
******************************************************************************/
#define TIMERMESSAGE_EV  		2	/* Not yet implemented */	
#define PERIODICTIMER_EV		3	/* Not yet implemented */
#define _LASTEV 				0x5F

/* RTOS Timer structure */

#define TmrNext         		0	/* Pointer to linked list element */
#define TmrEvent    			2	/* Object Associated event */
#define TmrCount        		4	/* Timer ticks till expired */
#define TmrQueue        		6	/* Task queue */
#define TmrSz           		6	/* Size of primitive Timer */
#define TmsSz           		6	/* Size of Timer Message */

/* RTOS Message Queue structure */

#define MsqSz           		4   /* Size of message queue */

#define MsqMessage      		0   /* Offset to Head of list of messages */
#define MsqPid          		2   /* Offset to Head of list of waiting processes */

/* Declare event to use across ASM code */  
#define EVENT(A) _GLOBAL(A, 2)		

/* Declare timer to use across RTOS code */
#define TIMER(A) _GLOBAL(A, TmrSz)	
		
/* Declare timer message to use across RTOS code */		
#define TIMERMESSAGE(A) _GLOBAL(A, TmsSz)	
	
/* Declare message queue to use across RTOS code */
#define MESSAGEQ(A) _GLOBAL(A, MsqSz)	

/******************************************************************************
** RTOS Kernel Critical Section macro definitions
******************************************************************************/

MACRO 	_ENTER_CRITICAL
	CLI
ENDM

MACRO 	_LEAVE_CRITICAL
	SEI
ENDM

MACRO	_RTOS_PROLOG
	RCALL	_EnterISR
ENDM


MACRO	_RTOS_EPILOG
	RJMP 	_LeaveISR
ENDM



#endif  /* __RTOS_INC__ */
